using System;
using System.Xml;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;

namespace MegaEngine.Source.Font
{
    /*
     * This class was written by ziggyware and is used in a demonstration of which the source is freely available
     * visit the article containing the source this font library is found in here: http://www.ziggyware.com/readarticle.php?article_id=52
     */
    
    public class XNAFont : IDisposable
    {
        string strFontFamily;
        Texture2D texture;
        SpriteBatch fontRenderer;
        public int Height;
        public int Kerning = 0;


        struct XNAFontUV
        {
            public float u, v;
            public int Width;

            public XNAFontUV(float u, float v, int Width)
            {
                this.u = u;
                this.v = v;
                this.Width = Width;
            }
        }

        Dictionary<char, XNAFontUV> UVData = new Dictionary<char, XNAFontUV>();

        public void OutputText(string str, int x, int y, Color col)
        {
            int iCurrentX = x;
            int iCurrentY = y;

            fontRenderer.Begin(SpriteBlendMode.AlphaBlend);
            foreach (char c in str)
            {
                XNAFontUV uv = UVData[c];

                if (c != ' ')
                {
                    fontRenderer.Draw(texture,
                        new Rectangle(iCurrentX, iCurrentY,
                            uv.Width, Height),
                        new Rectangle((int)(uv.v * texture.Height),
                                      (int)((1.0f - uv.u) * texture.Width),
                                      uv.Width, Height),
                        col);
                }

                iCurrentX += uv.Width - Kerning;
            }
            fontRenderer.End();
        }

        public static XNAFont LoadFont(GraphicsDevice device, string strXML, Texture2D texDDS)
        {
            XNAFont ret = new XNAFont();

            System.Xml.XmlTextReader tr = new XmlTextReader(strXML);
            while (tr.Read())
            {
                if (tr.Name == "Font")
                {
                    if (tr.AttributeCount > 0)
                    {
                        ret.strFontFamily = tr.GetAttribute("Family");
                        ret.Height = Convert.ToInt32(tr.GetAttribute("Height"));

                    }
                }
                else if (tr.Name == "Char")
                {
                    string str = tr.GetAttribute("c");
                    str = str.Replace("&qwo;", "\"");
                    str = str.Replace("&amp;", "&");
                    str = str.Replace("&lt;", "<");
                    str = str.Replace("&gt;", ">");
                    char c = str[0];

                    ret.UVData.Add(c,
                        new XNAFontUV(
                            Convert.ToSingle(tr.GetAttribute("u")),
                            Convert.ToSingle(tr.GetAttribute("v")),
                            Convert.ToInt32(tr.GetAttribute("width"))));

                }
            }
            tr.Close();

            ret.texture = texDDS;
            ret.fontRenderer = new SpriteBatch(device);

            return ret;
        }

        #region IDisposable Members

        public void Dispose()
        {
            if (texture != null)
                texture.Dispose();

            if (fontRenderer != null)
                fontRenderer.Dispose();

            texture = null;
            fontRenderer = null;
        }

        #endregion
    }

}
